package org.dfl.plugin.autoalign;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import org.dfl.plugin.editor.model.DflDiagram;
import org.dfl.plugin.editor.model.PlaceModelElement;
import org.dfl.plugin.editor.model.TransitionModelElement;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;

public class DflDiagramLayout {
	DflDiagram diagram;
	boolean isTB;
	Map<String, Point> oldLocations, newLocations;
	Map<String, Dimension> shifts;
	
	@SuppressWarnings("unchecked")
	public DflDiagramLayout(DflDiagram diagram, boolean isTB) {
		this.isTB = isTB;
		this.diagram = diagram;
		oldLocations = new HashMap<String, Point>();
		shifts = new  HashMap<String, Dimension>();

		for (PlaceModelElement placeME : diagram.getPlaces()) {
			oldLocations.put(placeME.getId(), placeME.getLocation());
			Dimension d = placeME.getSize();
			d.width = -d.width / 2;
			d.height = -d.height / 2;
			shifts.put(placeME.getId(), d);
		}
		for (TransitionModelElement transitionME : diagram.getTransitions()) {
			oldLocations.put(transitionME.getId(), transitionME.getLocation());
			Dimension d = transitionME.getSize();
			d.width = -d.width / 2;
			d.height = -d.height / 2;
			shifts.put(transitionME.getId(), d);
		}

		//some deep cloning just as future-proofing
		oldLocations = (Map<String, Point>) DeepCopy.copy(oldLocations);
	}
	
	public void computeNewLocations() {
		DotGenerator dg = new DotGenerator(diagram, isTB);
		InputStream xdot = GraphvizRunner.getStream(dg.toString());
		SvgParser svgParser = new SvgParser(xdot, shifts);
		newLocations  = svgParser.parse();
	}
	
	public void setNewLocations() {
		setLocations(newLocations);
	}
	
	public void setOldLocations() {
		setLocations(oldLocations);
	}
	
	private void setLocations(Map<String, Point> newLoc) {
		for (PlaceModelElement placeME : diagram.getPlaces())
			placeME.setLocation(newLoc.get(placeME.getId()));
		for (TransitionModelElement transitionME : diagram.getTransitions())
			transitionME.setLocation(newLoc.get(transitionME.getId()));
	}
}
